package arithmetic;

/**
 * @Author: Jie
 * @Date: 2019/3/11 10:19
 * @Function :
 * 191  位1的个数
 *
 * 编写一个函数，输入是一个无符号整数，返回其二进制表达式中数字位数为 ‘1’ 的个数（也被称为汉明重量）。
 * 示例 1：
 *
 * 输入：00000000000000000000000000001011
 * 输出：3
 * 解释：输入的二进制串 00000000000000000000000000001011 中，共有三位为 '1'。
 * 示例 2：
 *
 * 输入：00000000000000000000000010000000
 * 输出：1
 * 解释：输入的二进制串 00000000000000000000000010000000 中，共有一位为 '1'。
 * 示例 3：
 *
 * 输入：11111111111111111111111111111101
 * 输出：31
 * 解释：输入的二进制串 11111111111111111111111111111101 中，共有 31 位为 '1'。
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/number-of-1-bits
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 *
 * 231. 2的幂
 * 难度 简单
 * 给定一个整数，编写一个函数来判断它是否是 2 的幂次方。
 *
 * 示例 1:
 *
 * 输入: 1
 * 输出: true
 * 解释: 2^0 = 1
 */
public class A_21_Binary_NumOf1Bits {
    public static void main(String[] args) {
//        int count = hammingWeight(0b10000011);
        int count = hammingWeight2(0b11111111111111111111111111111101);
        System.out.println(count);
//        System.out.println( isPowerOfTwo(0));
        System.out.println(Integer.toBinaryString(-1));
        System.out.println(Integer.toBinaryString(0));
        System.out.println((Integer.MIN_VALUE));
        System.out.println((Integer.MIN_VALUE-1));
        System.out.println(0 & (0-1));
    }

    //判断每一位是否是1
    //	执行耗时:0 ms,击败了100.00% 的Java用户
    //	内存消耗:39.6 MB,击败了78.32% 的Java用户
    public static int hammingWeight1(int n) {
        int count = 0;
        while (n!=0){
            if ((n&1) == 1){
                count++;
            }
            n = n>>1;
        }
        return count;
    }

    /**
     *191   n = n & (n - 1);//消掉末端的1
     * //eg: 100100
     * //-1: 100011  //之前为1的数为了0，消掉1个1。
     *
     * //比上面的优势是，省略了。0的位置。所以快一点。最坏情况。一样。
     * @param n
     * @return
     */
    public static int hammingWeight2(int n) {
        int count = 0;
        while (n != 0) {
            count++;
            //eg: 3  00011
            //    2  00010
            //res:   00010
            //第二次  00001
            //res: 0

            //eg: 100100
            //-1: 100011  //之前为1的数为了0，消掉1个1。
            n = n & (n - 1);// n-1 .
        }
        return count;
    }

    /**
     * 231 给定一个整数，编写一个函数来判断它是否是 2 的幂次方。
     *
     * 因为 2 次幂， 有且仅有一个 是二进制位为 1 的数。 且者 n != 0;
     * 清零最低位 1 ，
     */
    public static boolean isPowerOfTwo(int n) {
//        if (n == Integer.MIN_VALUE || n==0)
        if (n <= 0)
            return false;
            return (n & (n-1)) == 0;//清零最低位 1 ，
    }

}
